-- MoonSaberMeter.lua

local start_time = nil
local end_time = nil

local total_damage = 0
local total_healed = 0

local unrecognized_damage_subevents = {}

function MoonSaberMeter_OnEvent(self, event, ...)
  -- using naming conventions at http://www.wowwiki.com/API_COMBAT_LOG_EVENT
  -- as of 2008-08-02

  local event_parameters = {arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19}
  local event_position = 1
  function next_parameter()
    output = event_parameters[event_position]
    event_position = event_position + 1
    return output
  end

  if event == "PLAYER_REGEN_DISABLED" then
    -- combat starting

    local current_time = GetTime()
    
    -- check if we just got out of combat
    if (total_damage > 0) and (end_time ~= nil) then
      gap = current_time - end_time
      if gap < 5 then
        DEFAULT_CHAT_FRAME:AddMessage(format('MoonSaberMeter: extending period (%d second gap)',  gap))
        end_time = nil
        return
      end
    end

    start_time = current_time
    end_time = nil

    total_damage = 0
    total_healed = 0

  elseif event == "PLAYER_REGEN_ENABLED" then
    -- combat ending

    if total_damage <= 0 then
      return
    end

    local current_time = GetTime()

    if start_time == nil then
      return
    end

    end_time = current_time

    local total_time = end_time - start_time
    if total_time < 1 then
      total_time = 1
    end

    DEFAULT_CHAT_FRAME:AddMessage(format('MoonSaberMeter: %d damage over %d seconds, %d DPS', 
                                         total_damage, total_time, total_damage / total_time))


  --elseif event == "UNIT_COMBAT" then
  --  -- basic damage event
  --  local unit, action, modifier, damage, damagetype = ...
  --  DEFAULT_CHAT_FRAME:AddMessage(format('U_C %s/%s/%s/%s/%s', unit, action, modifier, damage, damagetype))
  --
  --  if (unit == "player") or (unit == "pet") then
  --    if action == "HEAL" then
  --      total_healed = unit_combat_healed + damage
  --    else 
  --      unit_combat_damage = unit_combat_damage + damage
  --    end
  --  end

  elseif event == "COMBAT_LOG_EVENT_UNFILTERED" then
    -- using naming conventions at http://www.wowwiki.com/API_COMBAT_LOG_EVENT
    -- as of 2008-08-02

    local timestamp = next_parameter()
    local subevent = next_parameter()
    local sourceGUID = next_parameter()
    local sourceName = next_parameter()
    local sourceFlags = next_parameter()
    local destGUID = next_parameter()
    local destName = next_parameter()
    local destFlags = next_parameter()

    -- only look at damage events    
    if string.sub(subevent, -7) ~= '_DAMAGE' then
      return
    end

    -- skip messages that are not from current player
    if bit.band(sourceFlags, COMBATLOG_OBJECT_AFFILIATION_MINE) ~= COMBATLOG_OBJECT_AFFILIATION_MINE then
      return
    end

    -- prefix parameters (variable by action type)

    local spellId = nil
    local spellName = nil
    local spellSchool = nil
    local environmentalType = nil

    if string.sub(subevent, 1, 6) == 'SWING_' then
      -- none
      spellId = spellId
    elseif string.sub(subevent, 1, 6) == 'RANGE_' then
      spellId = next_parameter()
      spellName = next_parameter()
      spellSchool = next_parameter()
    elseif string.sub(subevent, 1, 6) == 'SPELL_' then
      spellId = next_parameter()
      spellName = next_parameter()
      spellSchool = next_parameter()
    elseif string.sub(subevent, 1, 15) == 'SPELL_PERIODIC_' then
      spellId = next_parameter()
      spellName = next_parameter()
      spellSchool = next_parameter()
    elseif string.sub(subevent, 1, 13) == 'ENVIRONMENTAL' then
      environmentalType = next_parameter()
    elseif not unrecognized_damage_subevents[subevent] then
      DEFAULT_CHAT_FRAME:AddMessage(format('unrecognized damage subevent %s', subevent))
      unrecognized_damage_subevents[subevent] = true
      return
    end

    -- standard damage parameters

    local amount = next_parameter()
    local school = next_parameter()
    local resisted = next_parameter()
    local blocked = next_parameter()
    local absorbed = next_parameter()
    local critical = next_parameter()
    local glancing = next_parameter()
    local crushing = next_parameter()

    total_damage = total_damage + amount

    --DEFAULT_CHAT_FRAME:AddMessage(format('%s/%s/%d', subevent, sourceName, amount))
  end
end

local frame = CreateFrame("Frame", "MoonSaberMeterFrame")
frame:SetScript("OnEvent", MoonSaberMeter_OnEvent)
frame:RegisterEvent("PLAYER_REGEN_DISABLED")
frame:RegisterEvent("PLAYER_REGEN_ENABLED")
--frame:RegisterEvent("UNIT_COMBAT")
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
